﻿<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Behaviour implementation boilerplate</Title>
      <Shortcut>ContosoUniversity_behaviour</Shortcut>
      <Description></Description>
      <Author>JK</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>handlerName</ID>
          <ToolTip>type of behaviour</ToolTip>
          <Default>ObjectCreate</Default>
        </Literal>
        <Literal>
          <ID>behaviour</ID>
          <ToolTip>type of behaviour</ToolTip>
          <Default>ObjectCreate</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[ 
        
        // Handler Name:    $groupId$Handlers$
        // Behaviour Name:  $behaviour$

    using ContosoUniversity.Core.Domain;
    using ContosoUniversity.Core.Domain.ContextualValidation;
    using ContosoUniversity.Core.Domain.InvariantValidation;
    using NRepository.Core;
    using System;
    using System.ComponentModel.DataAnnotations;

 
    // ************************************************************************************************
    // * Place this in the ContosoUniversity.Domain.Services.Tests/$grounpId$ folder 
    // * **********************************************************************************************
    #region Test Class
    using ContosoUniversity.Core.Domain.ContextualValidation;
    using NRepository.TestKit;
    using NUnit.Framework;
    using System;
    using System.Linq;
    using TestKit.Factories;
    
    [TestFixture]
    public class $behaviour$Tests 
    {
        // Prefer to leave this class at the top so easy to see what contistutes a valid command object
        public $behaviour$.Request CreateValidRequest(params Action<$behaviour$.Request>[] updates)
        {
            var commandModel = EntityGenerator.Create<$behaviour$.CommandModel>();

            var request = new $behaviour$.Request("UserId", commandModel);
            updates.ToList().ForEach(func => func(request));
            return request;
        }

        [Test]
        public void CheckInvariantValidationRules()
        {
            Action <$behaviour$.Request> CallSut = request =>
            {
                $groupId$Handlers.Handle(request);
            };

            // Assert2.CheckInvariantValidation("[ErrorMessage]", () => CallSut(CreateValidRequest(p => p.CommandModel. )));
        }

        [Test]
        public void CheckContextualValidationRules()
        {
            Func <$behaviour$.Request, ValidationMessageCollection > CallSut = request =>
            {
                var inMemoryRepository = new InMemoryRecordedRepository();
                var reponse = $groupId$Handlers.Handle(inMemoryRepository, request);
                return reponse.ValidationDetails;
            };

            // Assert2.CheckValidation( "[ExpectedMessage]", "[PropertyName]", () => CallSut(CreateValidRequest(p => p.CommandModel.DummyValue = "1")));           
        }

        [Test]
        public void When$behaviour$IsCalledThenIExpectItToDoSomething()
        {
        }
    }
 
  

        // ************************************************************************************************
        // * Place this in the $groupId$Handlers class found in the Services project
        // * **********************************************************************************************  
        public static $behaviour$.Response Handle(IRepository repository, $behaviour$.Request request)
        {
            //Remove me if autovalidation is found in the domainService decorator
            var validationDetails = Validator.ValidateRequest(request);
            if (validationDetails.HasValidationIssues)
                return new $behaviour$.Response(validationDetails);

            // ****************************************************************************
            //
            // Add your implementation here
            //
            // *****************************************************************************

            return new $behaviour$.Response();
        }


    public class $behaviour$
    {
        // $behaviour$.CommandModel
        public class CommandModel : ICommandModel
        {
            [Required]
            [StringLength(50, MinimumLength = 3)]
            public string DummyValue { get; set; }
        }

        // $behaviour$.Request
        public class Request : DomainRequest<CommandModel>
        {
            public Request(string userId, CommandModel commandModel)
                : base(userId, commandModel)
            {
                InvariantValidation = new InvariantValidation(this);
                ContextualValidation = new ContextualValidation(this);
            }
        }

        // $behaviour$.Response
        public class Response : DomainResponse
        {
            public Response() { }

            // If you are using the auto-validation 'decorator' do not change the signiture of this ctor (see AutoValidate<T>) in the 
            // DomainBootstrapper class
            public Response(ValidationMessageCollection validationDetails)
                : base(validationDetails)
            {
            }
        }

        // $behaviour$.InvariantValidation
        public class InvariantValidation : UserDomainRequestInvariantValidation<Request, CommandModel>
        {
            public InvariantValidation(Request context)
                : base(context)
            {
            }
        }

        // $behaviour$.ContextualValidation
        public class ContextualValidation : ContextualValidation<Request, CommandModel>
        {
            public ContextualValidation(Request context)
                : base(context)
            {
            }
        }
    }
]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>